#include "../include/mergeToVx.h"
#include "../include/busapi.h"
#include <stdio.h>

#define MY_CARD_TYPE	CPCI1553// CPCI1553// PCCD1553//
#define MY_INSTANCE     1
#define MY_CHANNEL		CHANNEL_1

static	BT_U16BIT			base_data = 0x0000; // Upper byte will increment on each buffer
static	int					active_buffer  = 0;
static	int					service_buffer = 1;
static   UINT               ch_id;
int bc_close = 0;

BT_INT _stdcall my_event_handler(BT_UINT cardnum, struct api_int_fifo *pFIFO);

void test_bc2() 
{
	UINT				status;
	API_BC_MBUF			bc_msg[2];	  // Structures to define BC messages
	int					i;
	API_INT_FIFO		sIntFIFO1;	  // For interrupt handling
	char				c;

    int dev_num, mode;
    bc_close=0;
	printf("Initializing API with BusTools_API_OpenChannel . . . ");

    // First find the device based on type and instance.
    dev_num = BusTools_FindDevice(MY_CARD_TYPE, MY_INSTANCE);
    if (dev_num < 0) printf("ERROR IN BUSTOOLS_FINDDEVICE.\n");

    // Open the device and get the channel id.
    mode = API_B_MODE | API_SW_INTERRUPT;  // 1553B protocol, use SW interrupts.
    status = BusTools_API_OpenChannel( &ch_id, mode, dev_num, MY_CHANNEL);

	if (status == API_SUCCESS) 
	{
		printf("Success.\n");

		status = BusTools_BM_Init(ch_id, 1, 1);

		// Select External Bus.
		printf("Bus select . . . ");
		status = BusTools_SetInternalBus(ch_id, 0);
		if (status != API_SUCCESS) printf("ERROR = %d\n",status);

		printf("BC Init . . . ");
		status = BusTools_BC_Init(ch_id, 0, BT1553_INT_END_OF_MESS, 0, 14, 12, 500000, 2);
		if (status != API_SUCCESS) printf("ERROR = %d\n",status);
		else
		{
			printf("\nMSG Alloc . . . ");
			status = BusTools_BC_MessageAlloc(ch_id, 2);
			if (status != API_SUCCESS) printf("ERROR = %d\n",status);
		
			printf("MSG 0 . . . ");
			memset(&bc_msg[0], 0, sizeof(bc_msg[0]));
			bc_msg[0].messno				= 0;		// Message number
			bc_msg[0].control = BC_CONTROL_MESSAGE;		// This is a standard BC message.
			bc_msg[0].control |= BC_CONTROL_CHANNELA;	// Send message on bus A (primary).
			bc_msg[0].control |= BC_CONTROL_BUFFERA;	// Using buffer A
			bc_msg[0].control |= BC_CONTROL_MFRAME_BEG;	// Beginning of minor frame.
			bc_msg[0].messno_next			= 1;		// Next message number, go to msg #1
			bc_msg[0].mess_command1.rtaddr	= 1;		// Command word 1, RT address
			bc_msg[0].mess_command1.subaddr = 1;		// Command word 1, Subaddress
			bc_msg[0].mess_command1.tran_rec = 0;		// Command word 1, transmit (1) or receive (0)
			bc_msg[0].mess_command1.wcount	= 0;		// Command word 1, word count, 0-31, 0=32 words
			bc_msg[0].gap_time				= 10;		// Intermessage gap time in microseconds

			// Initialize active data
			for (i=0; i<32; i++) bc_msg[0].data[0][i] = base_data + i;
			base_data += 0x0100;

			// Write the message to board memory
			status = BusTools_BC_MessageWrite(ch_id, 0, &bc_msg[0]);
			if (status != API_SUCCESS) printf("ERROR = %d\n",status);

			// Do the same thing again for the second message (1-T-2-32).
			printf("MSG 1 . . . ");
			memset(&bc_msg[1], 0, sizeof(bc_msg[1]));
			bc_msg[1].messno				= 1;		// Message number
			bc_msg[1].control = BC_CONTROL_MESSAGE;		// This is a standard BC message.
			bc_msg[1].control |= BC_CONTROL_CHANNELA;	// Send message on bus A (primary).
			bc_msg[1].control |= BC_CONTROL_BUFFERA;	// Using buffer A.
			bc_msg[1].control |= BC_CONTROL_MFRAME_END;	// End of minor frame.
			bc_msg[1].control |= BC_CONTROL_INTERRUPT;	// ENABLE INTERRUPT ON THIS MESSAGE.
			bc_msg[1].messno_next			= 0;		// Next message number, go to msg #0.
			bc_msg[1].mess_command1.rtaddr	= 1;		// Command word 1, RT address
			bc_msg[1].mess_command1.subaddr = 2;		// Command word 1, Subaddress
			bc_msg[1].mess_command1.tran_rec = 1;		// Command word 1, transmit (1) or receive (0)
			bc_msg[1].mess_command1.wcount	= 0;		// Command word 1, word count, 0-31, 0=32 words
			bc_msg[1].gap_time				= 10;		// Intermessage gap time in microseconds
			// Write the message to board memory
			status = BusTools_BC_MessageWrite(ch_id, 1, &bc_msg[1]);
			if (status != API_SUCCESS) printf("ERROR = %d\n",status);

			// Setup for our interrupt event handling functions
			memset(&sIntFIFO1, 0, sizeof(sIntFIFO1));
			sIntFIFO1.function       = my_event_handler;
			sIntFIFO1.iPriority      = THREAD_PRIORITY_BELOW_NORMAL;
			sIntFIFO1.dwMilliseconds = INFINITE;
			sIntFIFO1.iNotification  = 0;

			// Register for BC message events
			sIntFIFO1.FilterType     = EVENT_BC_MESSAGE;
            sIntFIFO1.FilterMask[1][1][2] = 0xFFFFFFFF;  // Enable all messages, RT1 TX SA2

			// Call the register function to register and start the thread.
			printf("\nRegistering event handler . . . ");
			status = BusTools_RegisterFunction(ch_id, &sIntFIFO1, REGISTER_FUNCTION);
			if (status != API_SUCCESS) printf("Error = %d.\n", status);
			else printf("Success.\n");

			// Start the bus controller, will start list at msg #0.
			printf("\nStart BC . . . ");
			
			status = BusTools_BC_StartStop(ch_id, 1);
			if (status != API_SUCCESS) printf("ERROR = %d\n",status);

			printf("\nBC running.  Hit any key to stop and exit.\n");
			//scanf("%c",&c);

			status = BusTools_BC_StartStop(ch_id, 0);
			if (status != API_SUCCESS) printf("ERROR = %d\n",status);
			else printf("Stopped.\n");

			// Un-Register our interrupt event handling functions
			printf("Unregistering event handler . . . ");
			status = BusTools_RegisterFunction(ch_id, &sIntFIFO1, UNREGISTER_FUNCTION);
			if (status != API_SUCCESS) printf("Error = %d.\n", status);
			else printf("Success.\n");
		} 
		
		// We're done.  Close API and board
		printf("\nClosing API . . . ");
		status = BusTools_API_Close(ch_id);
		if (status == API_SUCCESS)
			printf("Success.\n");
		else 
			printf("FAILURE, error = %d\n", status);
	} // End of if (initialization successful)
	else printf("FAILURE, error = %d\n", status);

	printf("FINISHED.\n");
} // End of main


/****************************************************************************
*
*  Function:  my_event_handler
*
*  Description:  Show how to register an interrupt thread and process the
*                resulting thread FIFO entries and interrupt calls.
*                This function processes the interrupt calls.
*
****************************************************************************/
BT_INT _stdcall my_event_handler(BT_UINT cardnum, struct api_int_fifo *sIntFIFO)
{
   BT_INT				tail;	           // FIFO Tail index
   BT_INT				status, i;
   API_BC_MBUF			bc_msg;

   logMsg("***into handle**\r\n",0,0,0,0,0,0);
   
   tail = sIntFIFO->tail_index;
   while ( tail != sIntFIFO->head_index )
   {
      if ( sIntFIFO->fifo[tail].event_type & EVENT_BC_MESSAGE )
      {
         //  Process a BC interrupt:
         //sIntFIFO->fifo[tail].buffer_off       // Byte address of buffer
         //sIntFIFO->fifo[tail].rtaddress        // RT address
         //sIntFIFO->fifo[tail].transrec         // Transmit/Receive
         //sIntFIFO->fifo[tail].subaddress       // Subaddress number
         //sIntFIFO->fifo[tail].wordcount        // Word count
         //sIntFIFO->fifo[tail].bufferID         // BC message number

		  // Handle message received from RT1 SA2 TRANSMIT
		  if ((sIntFIFO->fifo[tail].rtaddress  == 1) &&
			  (sIntFIFO->fifo[tail].transrec   == 1) &&
			  (sIntFIFO->fifo[tail].subaddress == 2)) 
		  {
			  // Read the second message
			  status = BusTools_BC_MessageRead(ch_id, 1, &bc_msg);
			  if (status == API_SUCCESS) 
			  {
				  // Swap active and service buffers
				  logMsg("***into handle**\r\n",0,0,0,0,0,0);
			  }
		  } // Done handling message received from RT1 SA2 TRANSMIT			
      }
      // Now update and store the tail pointer.
      tail++;                         // Next entry
      tail &= sIntFIFO->mask_index;   // Wrap the index
      sIntFIFO->tail_index = tail;    // Save the index
   }   
   bc_close = 1;
   return( API_SUCCESS );
}


